#include "plan.h"

namespace IAlib
{


Plan::Plan()
{
    m_Name = "";
}
//-------------------------------------------------------
Plan::Plan( const QString& Name )
{
    m_Name = Name;
}
//-------------------------------------------------------

Plan::Plan(const Plan & plan )
{
    m_Name = plan.m_Name;
	m_actions.clear();
    for (int i = 0; i < plan.m_actions.size(); i++)
    {
		addAction(*plan.m_actions[i]);
    }
}

//---------------------------------------------------------

Plan& Plan::operator=(const Plan& plan)
{
	m_Name = plan.m_Name;
	for (int i = 0; i < m_actions.size(); i++)
    {
        delete(m_actions[i]);
    }
	m_actions.clear();
    for (int i = 0; i < plan.m_actions.size(); i++)
    {
		addAction(*plan.m_actions[i]);
    }
	return *this;
}
//---------------------------------------------------------

Plan::~Plan()
{
    for (int i = 0; i < m_actions.size(); i++)
    {
        delete(m_actions[i]);
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Plan::addAction( const Action&  action )
{
    Action * newAction = new Action(action);
    m_actions.append(newAction);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////

int Plan::removeAction ( const int index )
{
    if (index < m_actions.size())
    {
        delete(m_actions[index]);
        m_actions.removeAt(index);
        return 1;
    }
    else
    {
        return -1;
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

unsigned int Plan::action_count() const
{
    return m_actions.size();
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////

QDomElement Plan::toXML(QDomDocument &doc)
{
    QDomElement ele = doc.createElement("plan");
    ele.setAttribute("planName", m_Name);
    QDomElement actions = doc.createElement("actions");
    for (int i = 0; i < m_actions.size(); i++)
    {
        QDomElement action = doc.createElement("actionPlan");
        if(m_actions[i]->getType() == 1)
        {
            action.setAttribute("idTarget", m_actions[i]->getID_target());
            action.setAttribute("idOrigine", m_actions[i]->getID_origine());
            action.setAttribute("idDialog", m_actions[i]->getDialogID());
            QDomElement message = doc.createElement("message");
            message.setAttribute("messageType",m_actions[i]->getMessage().getType());
            for (int j = 0; j < m_actions[i]->getMessage().getFacts().size(); j++)
            {
                message.appendChild(m_actions[i]->getMessage().getFacts()[j].toXML(doc));
            }
            action.appendChild(message);
        }
        action.setAttribute("ActionName", m_actions[i]->getName());
        action.setAttribute("mandatory", m_actions[i]->isMandatoty());
        action.setAttribute("attemptsNumber", m_actions[i]->getNbAttempts());
        actions.appendChild(action);
    }
    ele.appendChild(actions);
    return ele;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////

void Plan::fromXML(QDomElement element, QMap<QString, Action*> actions)
{
    m_Name = element.attribute("planName","");
    QDomNode actionNode = element.firstChild().firstChild();
    while (!actionNode.isNull())
    {
        QDomElement actionElement = actionNode.toElement();
        Action action = *actions[actionElement.attribute("ActionName","")];
        QString mandatory = actionElement.attribute("mandatory","");
        if ( !mandatory.isEmpty() )
        {
            if (mandatory.toInt() == 0)
            {
                action.setMandatory(false);
                QString nb_attempts = actionElement.attribute("attemptsNumber","");
                if (!nb_attempts.isEmpty())
                {
                    action.setNbAttempts(nb_attempts.toInt());
                }
                else
                {
                    action.setNbAttempts(-1);
                }
            }
            else
            {
                action.setMandatory(true);
                action.setNbAttempts(-1);
            }
        }
        else
        {
            action.setMandatory(true);
            action.setNbAttempts(-1);
        }

		if (action.getType() == 1)
		{
			action.setID_origine(actionElement.attribute("idOrigine",""));
			action.setID_target(actionElement.attribute("idTarget",""));
			action.setDialogID(actionElement.attribute("idDialog",""));
			QDomElement msg = actionElement.firstChild().toElement();
			QDomNode messageNode = actionElement.firstChild().firstChild();
			Message& m = action.getMessage();
			m.setType((Message::MessageType)msg.attribute("messageType","").toInt());
			while (!messageNode.isNull())
			{
				Fact fact;
				fact.fromXML(messageNode.toElement());
				m.addFact(fact);
				messageNode = messageNode.nextSibling();
			}
		}
        addAction(action);
        actionNode = actionNode.nextSibling();
    }
}

//---------------------------------------------

QByteArray Plan::toByteArray()
{
	QByteArray byte_array;
	QDataStream data(&byte_array, QIODevice::WriteOnly);
	data<<m_Name;
	data<<m_actions.size();
	for (int i = 0; i < m_actions.size(); i++)
	{
		QByteArray action_byte_array = m_actions[i]->toByteArray();;
		data<<action_byte_array;
	}
	return byte_array;
}

//--------------------------------------------

void Plan::fromByteArray(QByteArray& byte_array)
{
	QDataStream data(&byte_array, QIODevice::ReadOnly);
	data>>m_Name;
	int nb_action;
	data>>nb_action;
	for (int i = 0; i < nb_action; i++)
	{
		Action action;
		QByteArray action_byte_array;
		data>>action_byte_array;
		action.fromByteArray(action_byte_array);
		addAction(action);
	}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

QList<Action*> Plan::getActions() const
{
    return m_actions;
}


//--------------------------------

Action * Plan::getActionAt(const int index)
{
    if (index >= m_actions.size() || index < 0)
    {
        return NULL;
    }
    else
    {
        return m_actions[index];
    }
}

QString Plan::getName() const
{
    return m_Name;
}
void Plan::setName( const QString& Name)
{
    m_Name = Name;
}

}
